using System.IO;
using System.Reflection;
using NUnit.Framework;
using ODX.Core;
using ODX.LazyUnitTester;

namespace Refresh
{
    [Table("Human")]
    public abstract class Human : Entity
    {
        public abstract string Name { get; set;}
        public abstract int Age { get; set;}

        [Column("MasterID")]
        public abstract IEntityList<Pet> Pets { get; }
    }

    [Table("Pet")]
    public abstract class Pet : Entity
    {
        public abstract string Name { get; set;}
        public abstract Human Master { get; set; }
    }

    [TestFixture]
    public class C10_Refresh
    {
        [TestBody]
        static void Main()
        {
            const string filename = "pets.xml";
            if (File.Exists(filename))
                File.Delete(filename);

            Session s1 = new Session(new XmlDataProvider(filename));
            s1.RegisterAssembly(Assembly.GetExecutingAssembly());
            s1.Prepare();

            Session s2 = new Session(new XmlDataProvider(filename));
            s2.RegisterAssembly(Assembly.GetExecutingAssembly());
            s2.Prepare();

            // 1. Create and save object throug session s1
            Human john = s1.Create<Human>();
            john.Name = "John";
            john.Age = 23;

            Pet cat = s1.Create<Pet>();
            cat.Name = "Molly";
            john.Pets.Add(cat);

            s1.Save();

            // load, modify and save objects through session s2
            Human john2 = s2.SelectOne<Human>();
            john2.Age = 30;
            Pet cat2 = s2.SelectOne<Pet>();
            cat2.Delete(); // BUG!!! Refresh can't see deletions!!!
            Pet dog = s2.Create<Pet>();
            dog.Name = "Beethoven";
            dog.Master = john2;

            s2.Save();

            //look what session s1 stores in memory
            LUT.WriteLine("BEFORE REFRESH:");
            DescribeHuman(john);

            // Refresh (reload from storage)
            s1.Refresh();
            LUT.WriteLine("AFTER REFRESH:");
            DescribeHuman(john);
        }

        private static void DescribeHuman(Human john)
        {
            LUT.WriteLine("Now {0} is {1}. He masters", john.Name, john.Age);
            foreach (Pet pet in john.Pets)
                LUT.WriteLine("\t{0}", pet.Name);
            LUT.WriteLine();
            LUT.WriteLine("------------------------");
        }

        [Test]
        public void Test()
        {
            LUT.Execute(Main);
        }
    }
}
